package cn.honqun.tinycms.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckOr;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.honqun.tinycms.common.dto.Page;
import cn.honqun.tinycms.constants.SecurityConstants;
import cn.honqun.tinycms.domain.copier.UserCopier;
import cn.honqun.tinycms.domain.entity.Role;
import cn.honqun.tinycms.domain.entity.User;
import cn.honqun.tinycms.domain.vo.ChangePwdVO;
import cn.honqun.tinycms.domain.vo.GrantRolesVO;
import cn.honqun.tinycms.domain.vo.LoginVO;
import cn.honqun.tinycms.domain.vo.UserVO;
import cn.honqun.tinycms.service.UserService;
import cn.hutool.core.collection.ListUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/admin/user")
@RequiredArgsConstructor
@Tag(name = "UserController", description = "用户管理接口")
public class UserController {
    private final UserService userService;

    @PostMapping("/create")
    @Operation(summary = "创建用户", description = "创建用户，赋予缺省密码")
    @SaCheckRole(SecurityConstants.ROLE_SUPER)
    public UserVO create(@RequestBody @Valid UserVO userVO) {
        User user = UserCopier.INSTANCE.toUserBO(userVO);
        //缺省密码（登录账号+手机号后4位）
        String defaultPwd = user.getUsername() + user.getPhoneNum().substring(7);
        user.setPassword(defaultPwd);
        user = userService.create(user);

        return UserCopier.INSTANCE.toUserVO(user);
    }

    @PostMapping("/update")
    @Operation(summary = "更新用户", description = "只更新真实姓名，头像等")
    @SaCheckRole(SecurityConstants.ROLE_SUPER)
    public UserVO update(@RequestBody @Valid UserVO userVO) {
        User user = UserCopier.INSTANCE.toUserBO(userVO);
        user = userService.update(user);

        return UserCopier.INSTANCE.toUserVO(user);
    }

    @PostMapping("/enabled")
    @Operation(summary = "启用账号")
    @SaCheckRole(SecurityConstants.ROLE_SUPER)
    public void enabled(@RequestBody User user) {
        userService.enabled(user);
    }

    @PostMapping("/disabled")
    @Operation(summary = "禁用账号", description = "禁用账号，超级管理员账号不可禁用")
    @SaCheckRole(SecurityConstants.ROLE_SUPER)
    public void disabled(@RequestBody User user) {
        userService.disabled(user);
    }

    @PostMapping("/changePassword")
    @Operation(summary = "修改密码")
    @SaCheckLogin
    public void changePassword(@RequestBody ChangePwdVO changePwdVO) {
        userService.changePassword(changePwdVO);
    }

    @GetMapping("/selectById")
    @Operation(summary = "根据ID查询", description = "查询结果包括角色")
    @SaCheckLogin
    public UserVO selectById(Long id) {
        User user = userService.selectById(id);
        return UserCopier.INSTANCE.toUserVO(user);
    }

    @GetMapping("/select")
    @Operation(summary = "分页查询用户")
    @SaCheckRole(SecurityConstants.ROLE_SUPER)
    public Page<User> select(Page<User> page, UserVO userVO) {
        if (userVO.getRoleId() != null) {
            List<Role> roles = ListUtil.of(new Role(userVO.getRoleId()));
            userVO.setRoles(roles);
        }
        return userService.select(page, userVO);
    }

    @PostMapping("/grantRoles")
    @Operation(summary = "分配角色")
    @SaCheckRole(SecurityConstants.ROLE_SUPER)
    public void grantRoles(@RequestBody @Valid GrantRolesVO grantRolesVO) {
        List<Role> roles;
        if (grantRolesVO.getRoleIds() != null) {
            roles = grantRolesVO.getRoleIds().stream().map(Role::new).collect(Collectors.toList());
        } else {
            roles = Collections.emptyList();
        }
        userService.grantRoles(new User(grantRolesVO.getUserId()), roles);
    }

    @GetMapping("/selectUserRoles")
    @Operation(summary = "查询指定用户的角色")
    @SaCheckLogin
    public List<Role> selectUserRoles(@Parameter(description = "用户ID") Long userId) {
        return userService.selectRoles(new User(userId));
    }

    @PostMapping("/login")
    @Operation(summary = "用户名密码登录")
    @SaIgnore
    public UserVO login(@RequestBody @Valid LoginVO loginVO) {
        return userService.login(loginVO);
    }

}
